#include "dominion.h"
#include "dominion_helpers.h"
#include "rngs.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


const char * cardName(int card[10], int pos);
int cardnum(int card, int cardArray[10]);

int main()
{
	struct gameState G;
	int i, j, m, r, q;
	int k[10];			// array of kingdom cards
	int numPlayer;
	int randomSeed;
	int seed = 50;		// For comparison; guarantee similar random results
	int money;
	int highest;		// placeholder for highest value so far
	int highest2;
	int curPlayer;
	int boo;			// random boolean value
	
	int silver = 5;	//card number
	int gold = 6;	
	
	srand(seed);

	// Randomly determine kingdom cards, number of players
	for(i=0;i<10;i++)
	{
		r = (rand() % 19) + 7;
		while(cardnum(r, k) != -1)
			r = (rand() % 19) + 7;
		k[i] = r;
	}
	numPlayer = (rand() % 3) + 2;	// between 2 and 4.
	randomSeed = (rand() % 100)+1;
	
	// Initialize the game and output the number of players and the 10 cards chosen
	m = initializeGame(numPlayer, k, randomSeed, &G);
	printf("Playing game with %i players. Cards are:\n", numPlayer);
	for(i=0;i<10;i++)
		printf(" %s", cardName(k, i));
	printf(".\n");
	
	curPlayer = 0;
	int c = 0;
	while((!isGameOver(&G) && c < 50))		// Do a full game OR 50 turns
	{

		// Loop back to first player if necessary
		if(curPlayer == numPlayer)
			curPlayer = 0;
		barfGame(G, k, c, curPlayer);
		// Set money for the current turn
		money = 0;
		for(i=0;i<numHandCards(&G);i++) 
		{
			if (handCard(i, &G) == copper)
				money++;
			else if (handCard(i, &G) == silver)
				money += 2;
			else if (handCard(i, &G) == gold)
				money += 3;
		}
		// The "AI" for computer turns. Basically, it will just play the first card in its hand it can.
		// Repeat until out of cards or out of actions.
		// This should ensure a random spread of cards played.
		for(i=0;i<numHandCards(&G);i++)
		{
			if(handCard(i, &G) > 6)
			{
				switch(handCard(i, &G))
				{
					// FEAST card
					// Buy a random card. If not purchasable, loop through until one is found
					case 9:	printf("Attempting to play feast card... ");
							j = (rand() % 10) + 1;
							if(supplyCount(j, &G) > 0 && getCost(j) < 6)
							{
								printf("played!\n");
								playCard(i, j, -1, -1, &G);
							}
							else
							{
								q = j+1;
								while(q != j)
								{
									if(supplyCount(q, &G) > 0 && getCost(q) < 6)
									{	
										printf("played!\n");
										playCard(i, q, -1, -1, &G);
										q = j;
									}
									else
									{
										q++;
										if(q > 9)
											q = 0;
									}
								}
							}
							break;
					// MINE card
					// Loop through hand looking for a treasure card
					// Buy the next treasure up, if possible
					case 11:	printf("Attempting to play mine card... ");
								for(j=0;j<numHandCards(&G);j++)
									{
										if(handCard(j, &G) == 5 && G.supplyCount[silver] > 0)
										{
											printf("played!\n");
											playCard(i, j, 6, -1, &G);
											break;
										}
										else if(handCard(j, &G) == 6 && G.supplyCount[gold] > 0)
										{
											printf("played!\n");
											playCard(i, j, 7, -1, &G);
											break;
										}
									}
									break;
					// REMODEL card
					// Search for highest value card (gold or higher), then remodel it
					// to the highest supply card able
					case 12:		printf("Attempting to play remodel card... ");
									highest = -1;
									if(numHandCards(&G) == 1)
										break;
									for(j=0;j<numHandCards(&G);j++)
									{
										// Get the best hand card. Conditions:
										// Not below gold in value, more expensive than current highest 
										//(if there is a highest yet) and the card is not the remodel
										if(handCard(j, &G) > 7 && (getCost(handCard(j, &G)) >  getCost(handCard(highest, &G)) || highest == -1) && j != i)
											highest = j;
									}
									// default is to remodel to gold
									// if you can't afford the gold or better, don't remodel!
									if(handCard(highest, &G) > 3)
										highest2 = gold;
									else
										break;
									// find the most expensive you can afford and buy it
									for(j=0;j<10;j++)
									{
										if(getCost(k[j]) > getCost(highest2) && getCost(highest)+2 >= getCost(k[j]))
											highest2 = k[j];
									}
									printf("played!\n");
									playCard(i, highest, highest2, -1, &G);
									break;
								// BARON card
								// 50% chance to discard estate if owned
								// take the estate otherwise
					case 15:		printf("Attempting to play remodel card... ");
									boo = 0;
									for(j=0;j<numHandCards(&G);j++)
									{
										if(handCard(j, &G) == 5)
											boo = 1;
									}
									/*if(boo == 0 || rand() % 2 == 0)
									{
										printf("played!\n");
										playCard(i, 0, -1, -1, &G);
									}
									else
									{
										printf("played!\n");
										playCard(i, 1, -1, -1, &G);
									}*/
									break;
								// MINION card
								// 50% for each minion option
					case 17:	printf("Attempting to play minion card... played!\n");
								playCard(i, (rand() % 1), 1, -1, &G); //50% chance to get coins, 100% chance to discard if not
									break;
								// STEWARD card
								// 50% chance to get coins or cards
								// not implementing the trash; unsure how to implement it even semi-intelligently
					case 18:	printf("Attempting to play steward card... played!\n");
								if(rand() % 1)
										playCard(i, 1, -1, -1, &G);
									else
										playCard(i, -1, 1, -1, &G);
									break;
								// AMBASSADOR card
								// If cards < 2, do not play
								// Else, trash first non-ambassador card found
					case 20:	if(numHandCards(&G) > 1)
									{
										printf("Attempting to play ambassador card...");
										if(i == 0)
										{
											printf("played!\n");
											playCard(i, 1, 1, -1, &G);
										}
										else
										{
											printf("played!\n");
											playCard(i, 0, 1, -1, &G);
										}
									}
									break;
								// EMBARGO card
								// I simply embargo a random supply pile
								// As far as I can tell, a pile can have more than one embargo token,
								// so no logic checking required.
					case 22:	printf("Attempting to play embargo card... played!\n");
								playCard(i, rand() % 10, -1, -1, &G);
									break;
								// SALVAGER card
								// If cards < 2, do not play
								// Else, trash first non-salvager card found
					case 24:	printf("Attempting to play salvager card...");
								if(numHandCards(&G) > 1)
										{
											if(i == 0)
											{
												printf("played!\n");
												playCard(i, 1, 1, -1, &G);
											}
											else
											{
												printf("played!\n");
												playCard(i, 0, 1, -1, &G);
											}
										}
										break;	
								// All other cards
					default:	printf("Playing a card that does not require logic.\n");
								playCard(i, -1, -1, -1, &G);
								break;
				}
			}
		}
		// BUY phase
		// Try to buy a random supply card.
		// If it cannot afford, just loop through from there, buying the first one it can afford.
		printf("Money this turn: %i.\n", money);
		i = rand() % 10;
		if(getCost(k[i]) <= money)
		{	
			buyCard(k[i], &G);
			printf("%s card purchased.\n\n", cardName(k,i));
		}
		else
		{
			if(i==9)
				j = 0;
			else
				j = i+1;
			while(j != i)
			{
				if(getCost(k[j]) <= money)
				{
					buyCard(k[j], &G);
					printf("%s card purchased.\n\n", cardName(k, j));
					j = i;
				}
				else
					j++;
				if(j == 10)
					j = 0;
			}
		}
		endTurn(&G);
		curPlayer++;
		c++;
	}
	return 1;
}

// A function to simply print out the game state
void barfGame(struct gameState G, int card[10], int turn, int onPlayer)
{
	int i, j;
	printf("Report for turn %i:\n", turn);
	printf("Supply counts:");
	for(i=0;i<10;i++)
		printf(" %i", supplyCount(card[i], &G));
	printf(".\n");
		printf("Player %i's hand:", onPlayer+1);
		for(j=0;j<G.handCount[onPlayer];j++)
			printf(" %i", G.hand[onPlayer][j]);
		printf(".\n");
}

// helper function that checks which kingdom card a given card is.
// returns 0-9 on success, -1 if card is not in the current game
int cardnum(int card, int cardArray[10])
{
	int i;
	for(i=0;i<10;i++)
	{
		if(cardArray[i] == card)
			return i;
	}
	return -1;
}

// I thought I would need this. It turned out I didn't.
// BUT!
// Keeping it here for possible future use.
const char * cardName(int card[10], int pos)
{
	switch(card[pos])
	{
		case 7:	return "Adventurer";
						break;
		case 8:	return "Council Room";
							break;
		case 9:	return "Feast";
							break;
		case 10: return "Gardens";
							break;
		case 11: return "Mine";
						break;
		case 12: return "Remodel";
						break;
		case 13: return "Smithy";
						break;
		case 14: return "Village";
						break;
		case 15: return "Baron";
						break;
		case 16: return "Great Hall";
						break;
		case 17: return "Minion";
						break;
		case 18: return "Steward";
						break;
		case 19: return "Tribute";
						break;
		case 20: return "Ambassador";
						break;
		case 21: return "Cutpurse";
						break;
		case 22: return "Embargo";
						break;
		case 23: return "Outpost";
						break;
		case 24: return "Salvager";
						break;
		case 25: return "Sea Hag";
						break;
		case 26: return "Treasure Map";
						break;
	}
	return NULL;
}




